/*  EBDuplicateEditPanelController.m
 *  MESLib
 * 
 * Copyright 2003-2009 Starline Software Ltd
 * 
 * This file is part of MESLib.
 * 
 * MESLib is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * MESLib is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with MESLib. If not, see <http://www.gnu.org/licenses/>.
 */
//  Created by Tobias Haughton on Sat Jul 05 2003.
//

#import "SSEBDuplicateEditPanelController.h"
#import "SSCatalystDocument.h"

@implementation SSEBDuplicateEditPanelController

+ (id)sharedEBDuplicateEditPanelController {
   static SSEBDuplicateEditPanelController *sharedEBDuplicateEditPanelController = nil;

   if(!sharedEBDuplicateEditPanelController) {
      sharedEBDuplicateEditPanelController = [[SSEBDuplicateEditPanelController allocWithZone:[self zone]] init];
   }

   return sharedEBDuplicateEditPanelController;
}

- (id)init {
   self = [super initWithWindowNibName:@"EBDuplicateEditPanel"];
   if (self) {
      [self setWindowFrameAutosaveName:@"EBDuplicateEditPanel"];

   }
   return self;
}

- (void)awakeFromNib
{
   SSChartDate *today = [SSChartDate calendarDate];
   NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] initWithDateFormat:[NSString stringWithFormat:@"%@:%@:%@",
      @"%Y", @"%m", @"%d"] allowNaturalLanguage:NO] autorelease];
   [beginDateField setFormatter:dateFormatter];
   [endDateField setFormatter:dateFormatter]; //set the formatter for the 2 date fields
   [beginDateField setObjectValue:today];
   [endDateField setObjectValue:today];

   NSDateFormatter *timeFormatter = [[[NSDateFormatter alloc] initWithDateFormat:[NSString stringWithFormat:@"%@:%@:%@:%@",
      @"%H", @"%M", @"%S", @"%F"] allowNaturalLanguage:NO] autorelease];
   [beginTimeField setFormatter:timeFormatter];
   [endTimeField setFormatter:timeFormatter];
   [beginTimeField setObjectValue:today];
   [endTimeField setObjectValue:today];

   SSSourceFormatter *sourceFormatter = [[[SSSourceFormatter alloc] init] autorelease];
   [sourceCombobox setFormatter:sourceFormatter];

   //create SSColoredButtonCells for the label matrix
   SSColoredButtonCell *whiteButtonCell = [[SSColoredButtonCell alloc] initTextCell:[NSString string] backgroundColor:SSWhiteColor];
   [whiteButtonCell setTag:SSWhiteLabelType];
   [whiteButtonCell setButtonType:NSPushOnPushOffButton];
   [whiteButtonCell setBezelStyle:NSShadowlessSquareBezelStyle];
   [labelMatrix putCell:whiteButtonCell atRow:0 column:0];

   SSColoredButtonCell *yellowButtonCell = [[SSColoredButtonCell alloc] initTextCell:[NSString string] backgroundColor:SSYellowColor];
   [yellowButtonCell setTag:SSYellowLabelType];
   [yellowButtonCell setButtonType:NSPushOnPushOffButton];
   [yellowButtonCell setBezelStyle:NSShadowlessSquareBezelStyle];
   [labelMatrix putCell:yellowButtonCell atRow:0 column:1];

   SSColoredButtonCell *greenButtonCell = [[SSColoredButtonCell alloc] initTextCell:[NSString string] backgroundColor:SSGreenColor];
   [greenButtonCell setTag:SSGreenLabelType];
   [greenButtonCell setButtonType:NSPushOnPushOffButton];
   [greenButtonCell setBezelStyle:NSShadowlessSquareBezelStyle];
   [labelMatrix putCell:greenButtonCell atRow:0 column:2];

   SSColoredButtonCell *lightBlueButtonCell = [[SSColoredButtonCell alloc] initTextCell:[NSString string] backgroundColor:SSLightBlueColor];
   [lightBlueButtonCell setTag:SSLightBlueLabelType];
   [lightBlueButtonCell setButtonType:NSPushOnPushOffButton];
   [lightBlueButtonCell setBezelStyle:NSShadowlessSquareBezelStyle];
   [labelMatrix putCell:lightBlueButtonCell atRow:0 column:3];

   SSColoredButtonCell *blueButtonCell = [[SSColoredButtonCell alloc] initTextCell:[NSString string] backgroundColor:SSBlueColor];
   [blueButtonCell setTag:SSBlueLabelType];
   [blueButtonCell setButtonType:NSPushOnPushOffButton];
   [blueButtonCell setBezelStyle:NSShadowlessSquareBezelStyle];
   [labelMatrix putCell:blueButtonCell atRow:0 column:4];

   SSColoredButtonCell *purpleButtonCell = [[SSColoredButtonCell alloc] initTextCell:[NSString string] backgroundColor:SSPurpleColor];
   [purpleButtonCell setTag:SSPurpleLabelType];
   [purpleButtonCell setButtonType:NSPushOnPushOffButton];
   [purpleButtonCell setBezelStyle:NSShadowlessSquareBezelStyle];
   [labelMatrix putCell:purpleButtonCell atRow:0 column:5];

   SSColoredButtonCell *orangeButtonCell = [[SSColoredButtonCell alloc] initTextCell:[NSString string] backgroundColor:SSOrangeColor];
   [orangeButtonCell setTag:SSOrangeLabelType];
   [orangeButtonCell setButtonType:NSPushOnPushOffButton];
   [orangeButtonCell setBezelStyle:NSShadowlessSquareBezelStyle];
   [labelMatrix putCell:orangeButtonCell atRow:0 column:6];

   SSColoredButtonCell *redButtonCell = [[SSColoredButtonCell alloc] initTextCell:[NSString string] backgroundColor:SSRedColor];
   [redButtonCell setTag:SSRedLabelType];
   [redButtonCell setButtonType:NSPushOnPushOffButton];
   [redButtonCell setBezelStyle:NSShadowlessSquareBezelStyle];
   [labelMatrix putCell:redButtonCell atRow:0 column:7];

   [labelMatrix selectCellWithTag:SSWhiteLabelType];

   //add all of our fields to be watched for text entry
   [[SSTextEntryValidationMK2 sharedTextEntryValidation] addWatchedControl:sourceCombobox];
   [[SSTextEntryValidationMK2 sharedTextEntryValidation] addWatchedControl:actorCombobox];
   [[SSTextEntryValidationMK2 sharedTextEntryValidation] addWatchedControl:actionCombobox];
   [[SSTextEntryValidationMK2 sharedTextEntryValidation] addWatchedControl:locationCombobox];
   [[SSTextEntryValidationMK2 sharedTextEntryValidation] addWatchedControl:objectCombobox];
}

- (IBAction)showWindow:(id)sender
{
   [self showWindowForEvent:nil];
}

- (void)showWindowForEvent:(SSEventObject *)event
{
   if(event != nil && [event isKindOfClass:[SSEventObject class]]) {
      [self setRepresentedObject:event];
      //display our panel in a model session
      NSModalSession session;

      [self window];

      [self setControlValues];

      session = [NSApp beginModalSessionForWindow:[self window]];
      for (;;) {
         if ([NSApp runModalSession:session] != NSRunContinuesResponse)
            break;
      }
      [NSApp endModalSession:session];
   }
}

- (void)setControlValues
{
   if([[self representedObject] source]) {
      [sourceCombobox setObjectValue:[(SSEventObject *)[self representedObject] source]];
   } else {
      [sourceCombobox setObjectValue:[NSArray array]];
   }

   if([(SSEventObject *)[self representedObject] actor]) {
      [actorCombobox setStringValue:[(SSEventObject *)[self representedObject] actor]];
   } else {
      [actorCombobox setStringValue:@""];
   }

   if([(SSEventObject *)[self representedObject] action]) {
      [actionCombobox setStringValue:[(SSEventObject *)[self representedObject] action]];
   } else {
      [actionCombobox setStringValue:@""];
   }

   if([(SSEventObject *)[self representedObject] location]) {
      [locationCombobox setStringValue:[(SSEventObject *)[self representedObject] location]];
   } else {
      [locationCombobox setStringValue:@""];
   }

   if([(SSEventObject *)[self representedObject] object]) {
      [objectCombobox setStringValue:[(SSEventObject *)[self representedObject] object]];
   } else {
      [objectCombobox setStringValue:@""];
   }

   if([(SSEventObject *)[self representedObject] remark]) {
      [remarkCombobox setStringValue:[(SSEventObject *)[self representedObject] remark]];
   } else {
      [remarkCombobox setStringValue:@""];
   }

   if([(SSEventObject *)[self representedObject] label]) {
      [labelMatrix selectCellWithTag:[[(SSEventObject *)[self representedObject] label] intValue]];
   } else {
      [labelMatrix selectCellWithTag:SSWhiteLabelType];
   }

   if([(SSEventObject *)[self representedObject] beginTime]) {
      [beginDateField setObjectValue:[(SSEventObject *)[self representedObject] beginTime]];
      [beginTimeField setObjectValue:[(SSEventObject *)[self representedObject] beginTime]];
      [beginTimeCheckBox setState:![[(SSEventObject *)[self representedObject] beginTime] isEstimated]];
   } else {
      [beginDateField setStringValue:@""];
      [beginTimeField setStringValue:@""];
      [beginTimeCheckBox setState:NSOffState];
   }

   if([(SSEventObject *)[self representedObject] endTime]) {
      [endDateField setObjectValue:[(SSEventObject *)[self representedObject] endTime]];
      [endTimeField setObjectValue:[(SSEventObject *)[self representedObject] endTime]];
      [endTimeCheckBox setState:![[(SSEventObject *)[self representedObject] endTime] isEstimated]];
   } else {
      [endDateField setStringValue:@""];
      [endTimeField setStringValue:@""];
      [endTimeCheckBox setState:NSOffState];
   }
}

- (IBAction)commitData:(id)sender
{
   if(![[sourceCombobox objectValue] isEqualTo:[(SSEventObject *)representedObject source]]) { //if it hasn't changed don't set the same value
      [(SSEventObject *)representedObject setSource:[sourceCombobox objectValue]];
   }

   if(![[actorCombobox stringValue] isEqualToString:[(SSEventObject *)representedObject actor]]) { //if it hasn't changed don't set the same value
      [(SSEventObject *)representedObject setActor:[actorCombobox stringValue]];
   }

   if(![[actionCombobox stringValue] isEqualToString:[(SSEventObject *)representedObject action]]) { //if it hasn't changed don't set the same value
      [(SSEventObject *)representedObject setAction:[actionCombobox stringValue]];
   }

   if(![[objectCombobox stringValue] isEqualToString:[(SSEventObject *)representedObject object]]) { //if it hasn't changed don't set the same value
      [(SSEventObject *)representedObject setObject:[objectCombobox stringValue]];
   }

   if(![[locationCombobox stringValue] isEqualToString:[(SSEventObject *)representedObject location]]) { //if it hasn't changed don't set the same value
      [(SSEventObject *)representedObject setLocation:[locationCombobox stringValue]];
   }

   if(![[remarkCombobox stringValue] isEqualToString:[(SSEventObject *)representedObject remark]]) { //if it hasn't changed don't set the same value
      [(SSEventObject *)representedObject setRemark:[remarkCombobox stringValue]];
   }

   if(![[labelMatrix selectedCell] tag] != [[representedObject label] intValue]) { //if it hasn't changed don't set the same value
      [(SSEventObject *)representedObject setLabel:[NSNumber numberWithInt:[[labelMatrix selectedCell] tag]]];
   }

   [(SSEventObject *)representedObject setBeginTime:[self beginTimeFromFields]];
   [(SSEventObject *)representedObject setEndTime:[self endTimeFromFields]];


   
   [NSApp stopModal];
   [self close];
}

- (BOOL)control:(NSControl *)control didFailToFormatString:(NSString *)string 
        errorDescription:(NSString *)error
{
   if([control isEqualTo:beginTimeField] || [control isEqualTo:endTimeField]) {
      //break the string into it's time segments
      NSArray *timeArray = [string componentsSeparatedByString:@":"];
      NSString *timeString = [NSString string];
      int i = 0;

      while(i < [timeArray count] && i < 4) {
         //include the < 4 incase the user has entered too many values
         timeString = [timeString stringByAppendingString:[timeArray objectAtIndex:i]]; //add the time value to the string

         if(i < 3) {
            //add the seperator
            timeString = [timeString stringByAppendingString:@":"];
         }

         i++;
      }

      while(i < 4) {
         //we have used all of the user entered values so pad with 0
         timeString = [timeString stringByAppendingString:@"0"];

         if(i < 3) {
            //add the seperator
            timeString = [timeString stringByAppendingString:@":"];
         }

         i++;
      }

      SSChartDate *cd = [[[SSChartDate alloc] initWithString:timeString calendarFormat:@"%H:%M:%S:%F"] autorelease];

      if(cd) {
         //the new date is valid so set the fields value to that
         [control setObjectValue:cd];
      } else {
         //the user entered un usable info so set the date to now
         [control setObjectValue:[SSChartDate calendarDate]];
      }
   } else if([control isEqualTo:beginDateField] || [control isEqualTo:endDateField]) {
      //it's a date
      [control setObjectValue:[SSChartDate calendarDate]];
   }

   return NO;
}

- (SSEventObject *)representedObject
{
   return representedObject;   
}

- (void)setRepresentedObject:(SSEventObject *)event
{
   representedObject = event;   
}

- (SSChartDate *)beginTimeFromFields
{
   BOOL timeIsEstimated;
   SSChartDate *finalDate;
   NSCalendarDate *dateObject = [beginDateField objectValue];
   NSCalendarDate *timeObject = [beginTimeField objectValue];

   if([beginTimeCheckBox state]) {
      timeIsEstimated = NO;
   } else {
      timeIsEstimated = YES;
   }

   if(dateObject && timeObject) {
      //ther is a begin date and time so joing them into the same date
      finalDate = [[[SSChartDate alloc] initWithString:[NSString stringWithFormat:@"%@/%@/%@/%@/%@/%@/%@", [dateObject descriptionWithCalendarFormat:@"%Y"],
         [dateObject descriptionWithCalendarFormat:@"%m"], [dateObject descriptionWithCalendarFormat:@"%d"], [timeObject descriptionWithCalendarFormat:@"%H"],
         [timeObject descriptionWithCalendarFormat:@"%M"], [timeObject descriptionWithCalendarFormat:@"%S"], [timeObject descriptionWithCalendarFormat:@"%F"]]
                                        calendarFormat:@"%Y/%m/%d/%H/%M/%S/%F" isEstimated:timeIsEstimated] autorelease];
   } else {
      if(dateObject) {
         //there is a begin date but no time
         finalDate = [SSChartDate chartDateWithCalendarDate:dateObject isEstimated:timeIsEstimated];
      } else {
         if(timeObject) {
            //there is a time but no date
            finalDate = [SSChartDate chartDateWithCalendarDate:timeObject isEstimated:timeIsEstimated];
         } else {
            //there is no time or date
            finalDate = [SSChartDate chartDateWithCalendarDate:[NSCalendarDate calendarDate] isEstimated:timeIsEstimated];
         }
      }
   }

   return finalDate;
}

- (SSChartDate *)endTimeFromFields
{
   BOOL timeIsEstimated;
   SSChartDate *finalDate;
   NSCalendarDate *dateObject = [endDateField objectValue];
   NSCalendarDate *timeObject = [endTimeField objectValue];

   if([endTimeCheckBox state]) {
      timeIsEstimated = NO;
   } else {
      timeIsEstimated = YES;
   }

   if(dateObject && timeObject) {
      //ther is a end date and time so joing them into the same date
      finalDate = [[[SSChartDate alloc] initWithString:[NSString stringWithFormat:@"%@/%@/%@/%@/%@/%@/%@", [dateObject descriptionWithCalendarFormat:@"%Y"],
         [dateObject descriptionWithCalendarFormat:@"%m"], [dateObject descriptionWithCalendarFormat:@"%d"], [timeObject descriptionWithCalendarFormat:@"%H"],
         [timeObject descriptionWithCalendarFormat:@"%M"], [timeObject descriptionWithCalendarFormat:@"%S"], [timeObject descriptionWithCalendarFormat:@"%F"]]
                                        calendarFormat:@"%Y/%m/%d/%H/%M/%S/%F" isEstimated:timeIsEstimated] autorelease];
   } else {
      if(dateObject) {
         //there is a end date but no time
         finalDate = [SSChartDate chartDateWithCalendarDate:dateObject isEstimated:timeIsEstimated];
      } else {
         if(timeObject) {
            //there is a time but no date
            finalDate = [SSChartDate chartDateWithCalendarDate:timeObject isEstimated:timeIsEstimated];
         } else {
            //there is no time or date
            finalDate = [SSChartDate chartDateWithCalendarDate:[NSCalendarDate calendarDate] isEstimated:timeIsEstimated];
         }
      }
   }

   return finalDate;
}

//***********************************combobox datasource
- (int)numberOfItemsInComboBox:(NSComboBox *)aComboBox
{
   switch([aComboBox tag]) {
      case 101:
         return [[[NSDocumentController sharedDocumentController] currentDocument] numberOfUniqueSources];
         break;
      case 102:
         return [[[NSDocumentController sharedDocumentController] currentDocument] numberOfUniqueActors];
         break;
      case 103:
         return [[[NSDocumentController sharedDocumentController] currentDocument] numberOfUniqueActions];
         break;
      case 104:
         return [[[NSDocumentController sharedDocumentController] currentDocument] numberOfUniqueLocations];
         break;
      case 105:
         return [[[NSDocumentController sharedDocumentController] currentDocument] numberOfUniqueObjects];
         break;
      case 106:
         return [[[NSDocumentController sharedDocumentController] currentDocument] numberOfUniqueRemarks];
         break;
      default:
         return 0;
         break;
   }
}

- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(int)index
{
   id record = nil;

   switch([aComboBox tag]) {
      case 101:
         record = [[[NSDocumentController sharedDocumentController] currentDocument] alphabeticDataSourceDictionaryArrayWithKey:@"source" objectAtIndex:index];
         break;
      case 102:
         record = [[[NSDocumentController sharedDocumentController] currentDocument] alphabeticDataSourceDictionaryArrayWithKey:@"actor" objectAtIndex:index];
         break;
      case 103:
         record = [[[NSDocumentController sharedDocumentController] currentDocument] alphabeticDataSourceDictionaryArrayWithKey:@"action" objectAtIndex:index];
         break;
      case 104:
         record = [[[NSDocumentController sharedDocumentController] currentDocument] alphabeticDataSourceDictionaryArrayWithKey:@"location" objectAtIndex:index];
         break;
      case 105:
         record = [[[NSDocumentController sharedDocumentController] currentDocument] alphabeticDataSourceDictionaryArrayWithKey:@"object" objectAtIndex:index];
         break;
      case 106:
         record = [[[NSDocumentController sharedDocumentController] currentDocument] alphabeticDataSourceDictionaryArrayWithKey:@"remark" objectAtIndex:index];
         break;
      default:
         break;
   }

   return record;
}


@end
